<template>
  <div class="min-h-screen font-inter bg-gradient-to-br from-dark to-[#0F172A] text-light">
    <header class="py-6 px-4 md:px-8">
      <div class="max-w-7xl mx-auto">
        <h1 class="text-[clamp(1.8rem,4vw,3rem)] font-bold text-center text-white drop-shadow-lg"
          >创意3D画廊</h1
        >
        <p class="text-center text-gray-300 mt-2 max-w-2xl mx-auto"
          >探索这个使用CSS 3D变换创建的沉浸式画廊，体验独特的3D视觉效果</p
        >
      </div>
    </header>

    <main class="max-w-7xl mx-auto px-4 py-12">
      <div class="gallery-container perspective-1000">
        <div
          id="carousel"
          class="carousel preserve-3d"
          :style="{ transform: `rotateY(${currentRotation}deg)` }"
          @mousedown="startDrag"
          @touchstart="startDrag"
          @mouseenter="pauseAutoPlay"
          @mouseleave="resumeAutoPlay"
        >
          <div
            v-for="(item, index) in galleryItems"
            :key="index"
            class="carousel-item"
            :style="{ '--i': index }"
          >
            <div v-if="!item.loaded" class="image-skeleton"></div>
            <img
              v-else
              :src="item.src"
              :alt="item.alt"
              :class="!item.loaded ? 'image-fade-in ' : 'fade-img'"
              :style="{ animationDelay: `${index * 0.1}s` }"
            />
          </div>
        </div>

        <button
          id="prevBtn"
          class="nav-btn prev animate-fade-in"
          style="animation-delay: 0.2s"
          @click="rotate(-rotationStep)"
        >
          <i class="fa-solid fa-chevron-left"></i>
        </button>
        <button
          id="nextBtn"
          class="nav-btn next animate-fade-in"
          style="animation-delay: 0.4s"
          @click="rotate(rotationStep)"
        >
          <i class="fa-solid fa-chevron-right"></i>
        </button>
      </div>

      <div class="gallery-indicators" id="indicators">
        <div
          v-for="(item, index) in galleryItems"
          :key="index"
          class="indicator animate-fade-in"
          :style="{ 'animation-delay': `${0.6 + index * 0.1}s` }"
          :class="{ active: activeIndex === index }"
          @click="goToIndex(index)"
        >
        </div>
      </div>

      <div class="gallery-info animate-fade-in" style="animation-delay: 1.5s">
        <h2 class="gallery-title">沉浸式3D体验</h2>
        <p class="gallery-desc">
          这个创意画廊利用CSS
          3D变换技术，将图片排列在一个虚拟的圆柱体表面，创造出令人惊叹的3D视觉效果。
          你可以通过点击导航按钮或直接拖拽来旋转画廊，查看不同角度的图片。每张图片都有精心设计的悬停效果，
          当你将鼠标悬停在图片上时，它会向前突出并放大，增强了交互体验和深度感。
        </p>
      </div>
    </main>
  </div>
</template>

<script setup>
  import { ref, onMounted, onUnmounted, computed } from 'vue'

  // 画廊配置
  const rotationStep = 45
  const autoPlayIntervalTime = 5000

  // 响应式状态
  const currentRotation = ref(0)
  const isDragging = ref(false)
  const startX = ref(0)
  const startRotation = ref(0)
  const autoPlayInterval = ref(null)

  // 画廊图片数据
  const galleryItems = ref([
    { src: 'https://picsum.photos/id/1018/600/800', alt: '风景照片1', loaded: false },
    { src: 'https://picsum.photos/id/1015/600/800', alt: '风景照片2', loaded: false },
    { src: 'https://picsum.photos/id/1019/600/800', alt: '风景照片3', loaded: false },
    { src: 'https://picsum.photos/id/1039/600/800', alt: '风景照片4', loaded: false },
    { src: 'https://picsum.photos/id/1043/600/800', alt: '风景照片5', loaded: false },
    { src: 'https://picsum.photos/id/1045/600/800', alt: '风景照片6', loaded: false },
    { src: 'https://picsum.photos/id/1059/600/800', alt: '风景照片7', loaded: false },
    { src: 'https://picsum.photos/id/1061/600/800', alt: '风景照片8', loaded: false }
  ])

  // 计算当前激活的索引
  const activeIndex = computed(() => {
    return Math.round((-currentRotation.value % 360) / rotationStep) % galleryItems.value.length
  })

  // 旋转画廊
  const rotate = (step) => {
    currentRotation.value += step
  }

  // 跳转到指定索引
  const goToIndex = (index) => {
    const targetRotation = index * -rotationStep
    const diff = targetRotation - currentRotation.value
    currentRotation.value += diff
  }

  // 拖拽相关方法
  const startDrag = (e) => {
    isDragging.value = true
    startX.value = e.type.includes('mouse') ? e.clientX : e.touches[0].clientX
    startRotation.value = currentRotation.value

    // 暂停过渡效果，使拖拽更流畅
    const carousel = document.getElementById('carousel')
    if (carousel) carousel.style.transition = 'none'
  }

  const drag = (e) => {
    if (!isDragging.value) return

    const clientX = e.type.includes('mouse') ? e.clientX : e.touches[0].clientX
    const diffX = (clientX - startX.value) * 0.5
    currentRotation.value = startRotation.value - diffX
  }

  const endDrag = () => {
    if (!isDragging.value) return

    isDragging.value = false

    // 恢复过渡效果
    const carousel = document.getElementById('carousel')
    if (carousel) carousel.style.transition = 'transform 0.5s ease-out'

    // 吸附到最近的图片位置
    currentRotation.value = Math.round(currentRotation.value / rotationStep) * rotationStep
  }

  // 自动播放控制
  const startAutoPlay = () => {
    autoPlayInterval.value = setInterval(() => {
      rotate(-rotationStep)
    }, autoPlayIntervalTime)
  }

  const pauseAutoPlay = () => {
    if (autoPlayInterval.value) {
      clearInterval(autoPlayInterval.value)
    }
  }

  const resumeAutoPlay = () => {
    pauseAutoPlay()
    startAutoPlay()
  }

  const preloadImages = async () => {
    const loadPromises = galleryItems.value.map((item) => {
      return new Promise((resolve) => {
        const img = new Image() // 创建一个虚拟图片对象
        img.src = item.src // 触发图片加载

        // 图片加载完成时
        img.onload = () => {
          item.loaded = true // 更新状态为“已加载”
          resolve()
        }

        // 图片加载失败时（避免阻塞）
        img.onerror = () => {
          item.loaded = true // 即使失败也标记为“已处理”，避免一直显示骨架屏
          resolve()
        }
      })
    })
    await Promise.all(loadPromises) // 等待所有图片加载完成
  }
  // 生命周期钩子
  onMounted(() => {
    preloadImages()

    // 开始自动播放
    startAutoPlay()

    // 添加全局事件监听
    document.addEventListener('mousemove', drag)
    document.addEventListener('touchmove', drag, { passive: true })
    document.addEventListener('mouseup', endDrag)
    document.addEventListener('touchend', endDrag)
  })

  onUnmounted(() => {
    // 清理定时器和事件监听
    pauseAutoPlay()
    document.removeEventListener('mousemove', drag)
    document.removeEventListener('touchmove', drag)
    document.removeEventListener('mouseup', endDrag)
    document.removeEventListener('touchend', endDrag)
  })
</script>

<style scoped>
  @layer utilities {
    .content-auto {
      content-visibility: auto;
    }
    .perspective-1000 {
      perspective: 1000px;
    }
    .preserve-3d {
      transform-style: preserve-3d;
    }
    .backface-hidden {
      backface-visibility: hidden;
    }
    .rotate-y-0 {
      transform: rotateY(0deg);
    }
    .rotate-y-45 {
      transform: rotateY(45deg);
    }
    .rotate-y-90 {
      transform: rotateY(90deg);
    }
    .rotate-y-135 {
      transform: rotateY(135deg);
    }
    .rotate-y-180 {
      transform: rotateY(180deg);
    }
    .rotate-y-225 {
      transform: rotateY(225deg);
    }
    .rotate-y-270 {
      transform: rotateY(270deg);
    }
    .rotate-y-315 {
      transform: rotateY(315deg);
    }
    .transition-transform-slow {
      transition: transform 1s ease-out;
    }
  }

  .gallery-container {
    position: relative;
    width: 100%;
    height: 500px;
    display: flex;
    justify-content: center;
    align-items: center;
    margin: 90px 0 0 0;
  }

  .carousel {
    position: relative;
    width: 250px;
    height: 350px;
    transform-style: preserve-3d;
    transition: transform 1s ease;
  }

  .carousel-item {
    position: absolute;
    width: 100%;
    height: 100%;
    backface-visibility: hidden;
    border-radius: 10px;
    overflow: hidden;
    box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
    transition:
      transform 0.5s ease,
      box-shadow 0.5s ease;
  }

  .carousel-item:hover {
    box-shadow: 0 0 30px #9fbeff;
    transform: translateZ(20px);
  }

  .carousel-item img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.5s ease;
  }

  .carousel-item:hover img {
    transform: scale(1.05);
  }

  /* 图片位置计算 */
  .carousel-item:nth-child(1) {
    transform: rotateY(0deg) translateZ(320px);
  }
  .carousel-item:nth-child(2) {
    transform: rotateY(45deg) translateZ(320px);
  }
  .carousel-item:nth-child(3) {
    transform: rotateY(90deg) translateZ(320px);
  }
  .carousel-item:nth-child(4) {
    transform: rotateY(135deg) translateZ(320px);
  }
  .carousel-item:nth-child(5) {
    transform: rotateY(180deg) translateZ(320px);
  }
  .carousel-item:nth-child(6) {
    transform: rotateY(225deg) translateZ(320px);
  }
  .carousel-item:nth-child(7) {
    transform: rotateY(270deg) translateZ(320px);
  }
  .carousel-item:nth-child(8) {
    transform: rotateY(315deg) translateZ(320px);
  }

  .nav-btn {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    background: #53d3f1;
    color: white;
    border: none;
    border-radius: 50%;
    width: 50px;
    height: 50px;
    display: flex;
    justify-content: center;
    align-items: center;
    cursor: pointer;
    z-index: 10;
    transition: all 0.3s ease;
  }

  .nav-btn:hover {
    background: rgb(22, 142, 255);
    transform: translateY(-50%) scale(1.1);
    box-shadow: 0 0 15px rgb(22, 142, 255);
  }

  .nav-btn.prev {
    left: 10%;
  }

  .nav-btn.next {
    right: 10%;
  }

  .gallery-indicators {
    display: flex;
    justify-content: center;
    margin-top: 30px;
    gap: 10px;
  }
  .indicator {
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: rgba(121, 119, 119, 0.3);
    cursor: pointer;
    transition: all 0.3s ease;
  }

  .indicator.active {
    background: #3b82f6;
    transform: scale(1.4);
    box-shadow: 0 0 10px rgba(59, 130, 246, 0.6);
  }

  @keyframes fadeIn {
    from {
      opacity: 0;
      transform: translateY(20px);
    }
    to {
      opacity: 1;
      transform: translateY(0);
    }
  }

  .animate-fade-in {
    animation: fadeIn 0.8s ease forwards;
  }

  .gallery-info {
    max-width: 800px;
    margin: 30px auto;
    text-align: center;
    padding: 0 20px;
  }

  .gallery-title {
    font-size: clamp(1.8rem, 4vw, 2.8rem);
    font-weight: 800;
    letter-spacing: 0.03em;
    color: #53d3f1;
    text-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
  }

  .gallery-desc {
    font-size: clamp(1.05rem, 1.6vw, 1.2rem);
    color: rgba(240, 240, 255, 0.85);
    line-height: 1.75;
    max-width: 700px;
    margin: 0 auto;
  }

  @media (max-width: 768px) {
    .carousel {
      width: 180px;
      height: 260px;
    }

    .carousel-item:nth-child(n) {
      transform: rotateY(calc(var(--i) * 45deg)) translateZ(220px);
    }
  }

  @media (max-width: 480px) {
    .carousel {
      width: 140px;
      height: 200px;
    }

    .carousel-item:nth-child(n) {
      transform: rotateY(calc(var(--i) * 45deg)) translateZ(180px);
    }

    .gallery-title {
      font-size: 1.6rem;
    }

    .gallery-desc {
      font-size: 1rem;
      padding: 0 10px;
    }

    .nav-btn {
      width: 40px;
      height: 40px;
      font-size: 1rem;
    }
  }
  /* 骨架屏样式 */
  .image-skeleton {
    width: 100%;
    height: 100%;
    background: #2d3748;
    border-radius: 10px;
    animation: pulse 1.5s infinite;
  }

  .image-fade-in {
    opacity: 0;
    transition: opacity 0.6s ease;
    object-fit: cover;
  }
  .fade-img {
    opacity: 1;
  }
  /* 淡入动画 */
  .fade-in {
    opacity: 0;
    animation: fadeIn 0.5s ease forwards;
  }

  @keyframes pulse {
    0%,
    100% {
      opacity: 0.6;
    }
    50% {
      opacity: 0.3;
    }
  }

  @keyframes fadeIn {
    from {
      opacity: 0;
    }
    to {
      opacity: 1;
    }
  }
</style>
